﻿//SmartTimeFrames.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Smart
{
	using System;

	using Ecng.Common;
	using Ecng.Collections;

	using StClientLib;

	using StockSharp.BusinessEntities;

	/// <summary>
	/// Тайм-фреймы для исторических свечек SmartCOM.
	/// </summary>
	public sealed class SmartTimeFrames
	{
		private static readonly SynchronizedDictionary<StBarInterval, SmartTimeFrames> _intervals = new SynchronizedDictionary<StBarInterval, SmartTimeFrames>();
		private static readonly SynchronizedDictionary<TimeSpan, SmartTimeFrames> _values = new SynchronizedDictionary<TimeSpan, SmartTimeFrames>();

		private readonly TimeSpan _value;

		static SmartTimeFrames()
		{
			//Tick = new SmartTimeFrames(StBarInterval.StBarInterval_Tick, TimeSpan.FromSeconds(0.001));
			Minute1 = new SmartTimeFrames(StBarInterval.StBarInterval_1Min, TimeSpan.FromTicks(TimeSpan.TicksPerMinute));
			Minute5 = new SmartTimeFrames(StBarInterval.StBarInterval_5Min, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 5));
			Minute10 = new SmartTimeFrames(StBarInterval.StBarInterval_10Min, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 10));
			Minute15 = new SmartTimeFrames(StBarInterval.StBarInterval_15Min, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 15));
			Minute30 = new SmartTimeFrames(StBarInterval.StBarInterval_30Min, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 30));
			Hour1 = new SmartTimeFrames(StBarInterval.StBarInterval_60Min, TimeSpan.FromTicks(TimeSpan.TicksPerHour));
			Hour2 = new SmartTimeFrames(StBarInterval.StBarInterval_2Hour, TimeSpan.FromTicks(TimeSpan.TicksPerHour * 2));
			Hour4 = new SmartTimeFrames(StBarInterval.StBarInterval_4Hour, TimeSpan.FromTicks(TimeSpan.TicksPerHour * 4));
			Day = new SmartTimeFrames(StBarInterval.StBarInterval_Day, TimeSpan.FromTicks(TimeSpan.TicksPerDay));
			Week = new SmartTimeFrames(StBarInterval.StBarInterval_Week, TimeSpan.FromTicks(TimeSpanHelper.TicksPerWeek));
			Month1 = new SmartTimeFrames(StBarInterval.StBarInterval_Month, TimeSpan.FromTicks(TimeSpanHelper.TicksPerMonth));
			Month3 = new SmartTimeFrames(StBarInterval.StBarInterval_Quarter, TimeSpan.FromTicks(TimeSpanHelper.TicksPerMonth * 3));
			Year = new SmartTimeFrames(StBarInterval.StBarInterval_Year, TimeSpan.FromTicks(TimeSpanHelper.TicksPerYear));
		}

		private SmartTimeFrames(StBarInterval interval, TimeSpan value)
		{
			Interval = interval;

			_value = value;

			_intervals.Add(interval, this);
			_values.Add(value, this);
		}

		internal static SmartTimeFrames GetTimeFrame(StBarInterval interval)
		{
			return _intervals[interval];
		}

		internal static bool CanConvert(TimeSpan value)
		{
			return _values.ContainsKey(value);
		}

		///// <summary>
		///// Тиковый тайм-фрейм.
		///// </summary>
		//public static SmartTimeFrames Tick { get; private set; }

		/// <summary>
		/// Минутный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Minute1 { get; private set; }

		/// <summary>
		/// Пяти минутный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Minute5 { get; private set; }

		/// <summary>
		/// Десяти минутный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Minute10 { get; private set; }

		/// <summary>
		/// Пятнадцати минутный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Minute15 { get; private set; }

		/// <summary>
		/// Тридцати минутный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Minute30 { get; private set; }

		/// <summary>
		/// Часовой тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Hour1 { get; private set; }

		/// <summary>
		/// Двух часовой тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Hour2 { get; private set; }

		/// <summary>
		/// Четырех часовой тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Hour4 { get; private set; }

		/// <summary>
		/// Дневной тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Day { get; private set; }

		/// <summary>
		/// Недельный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Week { get; private set; }

		/// <summary>
		/// Месячный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Month1 { get; private set; }

		/// <summary>
		/// Трех месячный тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Month3 { get; private set; }

		/// <summary>
		/// Годовой тайм-фрейм.
		/// </summary>
		public static SmartTimeFrames Year { get; private set; }

		internal StBarInterval Interval { get; private set; }

		/// <summary>
		/// Привести <see cref="TimeSpan"/> значение к объекту <see cref="SmartTimeFrames"/>.
		/// </summary>
		/// <param name="value"><see cref="TimeSpan"/> значение.</param>
		/// <returns>Объект <see cref="SmartTimeFrames"/>.</returns>
		public static implicit operator SmartTimeFrames(TimeSpan value)
		{
			if (!CanConvert(value))
				throw new ArgumentException("SmartCOM не поддерживает тайм-фрейм, равный {0}.".Put(value), "value");

			return _values[value];
		}

		/// <summary>
		/// Привести объект <see cref="SmartTimeFrames"/> к <see cref="TimeSpan"/> значению.
		/// </summary>
		/// <param name="timeFrame">Объект <see cref="SmartTimeFrames"/>.</param>
		/// <returns><see cref="TimeSpan"/> значение.</returns>
		public static explicit operator TimeSpan(SmartTimeFrames timeFrame)
		{
			if (timeFrame == null)
				throw new ArgumentNullException("timeFrame");

			return timeFrame._value;
		}

		internal Tuple<Security, SmartTimeFrames> GetToken(Security security)
		{
			return new Tuple<Security, SmartTimeFrames>(security, this);
		}
	}
}